// // // // // function Person(){};
// // // // let Person = function(){};
// // // // Person.prototype.name = 'silly';
// // // // Person.prototype.age = 25;
// // // // Person.prototype.sayName = function(){
// // // //     console.log(this.name);
// // // // }
// // // // let person1 = new Person();
// // // // let person2 = new Person();
// // // // console.log(person1.age);//25
// // // // console.log(person2.age);//25
// // // // person1.sayName();//silly
// // // // person2.sayName();//silly
// // // // console.log(person1.sayName === person2.sayName);//true

// // // //构造函数可以是函数表达式，也可以是函数声明，因此两种形式都可以
// // // function Person(){};
// // // //声明之后，构造函数就有了一个与之关联的原型对象：
// // // // console.log(typeof Person.prototype);//object
// // // // console.log(Person.prototype);//Person {}
// // // //{ 
// // // // constructor: f Person(), 
// // // // __proto__: Object
// // // //}
// // // // console.log(Person.prototype.constructor);//[Function: Person]
// // // // console.log(Person.prototype.__proto__);//{}

// // // // console.log(Person.prototype.constructor === Person);//true
// // // console.log(Person.prototype.__proto__ === Object.prototype);//true 原型也是一个对象，其构造函数是Object
// // // console.log(Person.prototype.__proto__.constructor === Object);//true
// // // console.log(Object.prototype.__proto__ === null);//true

// // // let person = new Person();
// // // console.log(person === Person); // false
// // // console.log(person.__proto__ === Person.prototype); // true 
// // // console.log(person.__proto__.constructor === Person); // true
// // // let person1 = new Person();
// // // let person2 = new Person();
// // // console.log(person1.__proto__ === person2.__proto__);//true
// // // console.log(Person.prototype.isPrototypeOf(person1));//true
// // // console.log(Person.prototype.isPrototypeOf(person2));//true
// // // console.log(Object.getPrototypeOf(person1) === Person.prototype);//true

// // let biped = { 
// // numLegs: 2 
// // }; 
// // let person = { 
// // name: 'Matt' 
// // };
// // console.log(person.__proto__);//{}
// // Object.setPrototypeOf(person, biped); 
// // console.log(person);//{ name: 'Matt' }
// // console.log(person.__proto__);//{ numLegs: 2 }
// // console.log(person.name); // Matt 
// // console.log(person.numLegs); // 2 
// // console.log(Object.getPrototypeOf(person) === biped); // true
// let biped = { 
// numLegs: 2 
// }; 
// console.log(biped.__proto__);//{}
// let person = Object.create(biped); 
// console.log(person.__proto__);//{ numLegs: 2 }
// console.log(person);//{}
// person.name = 'Matt'; 
// console.log(person);//{ name: 'Matt' }
// console.log(person.__proto__);//{ numLegs: 2 }
// console.log(person.name); // Matt 
// console.log(person.numLegs); // 2 
// console.log(Object.getPrototypeOf(person) === biped); // true

// function Person(){};
// Person.prototype.name = 'Scott';
// Person.prototype.age = 25;
// Person.prototype.job = 'a nurse';

// let person1 = new Person();
// let person2 = new Person();

// console.log(person1.hasOwnProperty('name')); //false person1实例上没有name属性
// person1.name = 'Alice';
// console.log(person1.hasOwnProperty('name')); //true person1实例上具有name属性
// console.log(person1.name);//Alice 来自实例
// console.log(person2.hasOwnProperty('name'));//false person2实例上没有name属性
// console.log(person2.name);//Scott 来自原型对象

// delete person1.name;
// console.log(person1.name);//Scott 来自原型对象
// console.log(person1.hasOwnProperty('name')); //false person1实例上没有name属性


// function Person(){};
// Person.prototype.name = 'Scott';
// Person.prototype.age = 25;
// Person.prototype.sayName = function(){
//     console.log(this.name);
// }
// let person1 = new Person();
// let person2 = new Person();
// console.log(person1.name); //Scott 从原型中获取
// console.log('name' in person1); //true in操作符
// person1.name = 'Alice';
// console.log(person1.name); //Alice 从实例中获取
// console.log('name' in person1); //true in操作符
// delete person1.name;
// console.log(person1.name); //Scott 从原型中获取
// console.log('name' in person1); //true in操作符

// function hasOwnPrototypeProperty(object,key){
//     return !object.hasOwnProperty(key) && key in object;
// }
// console.log(hasOwnPrototypeProperty(person1,'name'));//true 为原型属性
// console.log(hasOwnPrototypeProperty(person1,'name1'));//false 非原型属性
// person1.name = 'Alice';
// console.log(hasOwnPrototypeProperty(person1,'name'));//false 为实例属性

// function Person(){};
// Person.prototype.name = 'Scott';
// Person.prototype.age = 25;
// Person.prototype.sayName = function(){
//     console.log(this.name);
// };
// let person1 = new Person();
// let person2 = new Person();
// console.log(Object.keys(Person.prototype)); //[ 'name', 'age', 'sayName' ] 获取原型对象的所有可遍历属性
// console.log(Object.keys(person1));//[] 实例对象上的可遍历属性
// person1.name = 'Alice';
// person1.age = 26;
// console.log(Object.keys(person1));//[ 'name', 'age' ]实例对象上的可遍历属性

// console.log(Object.getOwnPropertyNames(Person.prototype));//[ 'constructor', 'name', 'age', 'sayName' ]
// console.log(Object.getOwnPropertyNames(person1));//[ 'name', 'age' ]

// for(let name of Object.keys(Person.prototype)){
//     console.log(name,Person.prototype[name]);
// }
// name Scott
// age 25
// sayName [Function]

// let s1 = Symbol('s11');
// let s2 = Symbol('s22');
// let obj = {
//     [s1]:'AAAAAA',
//     [s2]:'BBBBBB'
// }
// console.log(Object.getOwnPropertySymbols(obj));//[ Symbol(s11), Symbol(s22) ]

// let s1 = Symbol('s1');
// let s2 = Symbol('s2');
// let obj = {
//     1: 1,
//     first: 'first',
//     [s1]: 'symbol1',
//     second: 'second',
//     0: 0
// }
// obj[s2] = 'symbol2';
// obj[3] = 3;
// obj.third = 'third';
// obj[2] = 2;

// console.log(Object.getOwnPropertyNames(obj));//[ '0', '1', '2', '3', 'first', 'second', 'third' ]
// console.log(Object.getOwnPropertySymbols(obj));//[ Symbol(s1), Symbol(s2) ]
